package cn.ywyself.extend.utils;

/**
 * 转义工具集
 *
 * @author : ywyself
 * @created : 2018-10-10 8:51
 */
public class EscapeUtils {

    /**
     * Turn JavaScript special characters into escaped characters.
     * Escapes based on the JavaScript 1.5 recommendation.
     *
     * <p>Reference:
     * <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#String_literals">
     * JavaScript Guide</a> on Mozilla Developer Network.
     *
     * @param input the input string, can not be null
     * @return the string with escaped characters
     * @author Juergen Hoeller
     * @author Rob Harrop
     * @author Rossen Stoyanchev
     * @since 1.1.1
     */
    public static String escapeJavaScript(String input) {
        if (input == null) {
            return null;
        }
        StringBuilder filtered = new StringBuilder(input.length());
        char prevChar = '\u0000';
        char c;
        for (int i = 0; i < input.length(); i++) {
            c = input.charAt(i);
            if (c == '"') {
                // 双引号
                filtered.append("\\\"");
            } else if (c == '\'') {
                // 单引号
                filtered.append("\\'");
            } else if (c == '\\') {
                // 反斜杠
                filtered.append("\\\\");
            } else if (c == '/') {
                filtered.append("\\/");
            } else if (c == '\t') {
                // 制表符
                filtered.append("\\t");
            } else if (c == '\n') {
                // 换行符
                if (prevChar != '\r') {
                    filtered.append("\\n");
                }
            } else if (c == '\r') {
                // 回车符
                filtered.append("\\n");
            } else if (c == '\f') {
                // 换页符
                filtered.append("\\f");
            } else if (c == '\b') {
                // 退格符
                filtered.append("\\b");
            }
            // No '\v' in Java, use octal value for VT ascii char
            else if (c == '\013') {
                filtered.append("\\v");
            } else if (c == '<') {
                filtered.append("\\u003C");
            } else if (c == '>') {
                filtered.append("\\u003E");
            }
            // Unicode for PS (line terminator in ECMA-262)
            else if (c == '\u2028') {
                filtered.append("\\u2028");
            }
            // Unicode for LS (line terminator in ECMA-262)
            else if (c == '\u2029') {
                filtered.append("\\u2029");
            } else {
                filtered.append(c);
            }
            prevChar = c;
        }
        return filtered.toString();
    }

    /**
     * HTML 转义
     *
     * @param input 传入字符串
     * @return 转义后的字符串
     */
    public static String escapeHtml(String input) {
        StringBuilder escaped = new StringBuilder(input.length() * 2);
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            switch (c) {
                case '<':
                    escaped.append("&lt;");
                    break;
                case '>':
                    escaped.append("&gt;");
                    break;
                case '"':
                    escaped.append("&quot;");
                    break;
                case '\'':
                    escaped.append("&#39;");
                    break;
                case '&':
                    escaped.append("&amp;");
                    break;
                default:
                    escaped.append(c);
                    break;
            }
        }
        return escaped.toString();
    }
}
